/**
 * 版权所有(C)，上海海鼎信息工程股份有限公司，2008，所有权利保留。
 * 
 * 项目名：	rumba
 * 文件名：	MainFrame.java
 * 模块说明：	
 * 修改历史：
 * Feb 8, 2008 - lxm - 创建。
 */
package com.hd123.rumba.gwt.entry.client;

import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.LoadListener;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.gwtext.client.core.Margins;
import com.gwtext.client.core.RegionPosition;
import com.gwtext.client.widgets.Component;
import com.gwtext.client.widgets.Container;
import com.gwtext.client.widgets.MessageBox;
import com.gwtext.client.widgets.Panel;
import com.gwtext.client.widgets.TabPanel;
import com.gwtext.client.widgets.Viewport;
import com.gwtext.client.widgets.event.ContainerListenerAdapter;
import com.gwtext.client.widgets.layout.BorderLayout;
import com.gwtext.client.widgets.layout.BorderLayoutData;
import com.gwtext.client.widgets.layout.FitLayout;
import com.hd123.rumba.gwt.base.client.EntryPointBase;
import com.hd123.rumba.gwt.base.client.RBRemoteServiceAsync;
import com.hd123.rumba.gwt.base.client.exception.ClientBizException;
import com.hd123.rumba.gwt.base.client.util.GWTUtil;
import com.hd123.rumba.gwt.cartridge.client.CartridgeService;
import com.hd123.rumba.gwt.cartridge.client.biz.QCartridge;
import com.hd123.rumba.gwt.cpnts.module.client.ModuleNavigator;
import com.hd123.rumba.gwt.entry.client.entry.QEntry;
import com.hd123.rumba.gwt.entry.client.entry.QEntryLink;
import com.hd123.rumba.gwt.entry.client.menu.QMenu;
import com.hd123.rumba.gwt.entry.client.menu.QMenuItem;

/**
 * 应用程序主框架 | 程序入口
 * 
 * @author lxm
 * 
 */
public class MainFrame extends EntryPointBase {

  public void onModuleLoad() {
    super.onModuleLoad();
    try {
      this.moduleNavigator.add(MODULEURL_HOME);
      this.moduleNavigator.add(MODULEURL_CHANGEPWD, ModuleNavigator.VALUE_STYLE_ACTION);
      this.moduleNavigator.add(MODULEURL_ENTRY);

      drawSelf();
      loadCoverCartridge();

      this.moduleNavigator.prepare();

      this.showModule(MODULEURL_HOME);
    } catch (ClientBizException e) {
      MessageBox.alert(Window.getTitle(), "初始化时发生错误。\n" + e.getMessage());
    }
  }

  protected RBRemoteServiceAsync getRemoteService() {
    return MainFrameService.Locator.getService();
  }

  protected void onSessionLoad() {
    refreshLogInfo();
    wTopMenu.refresh();
  }

  /** 一个顶级菜单项被点击后的处理。 */
  public void clickTopMenuItem(QMenuItem menuItem) {
    assert wTopMenu != null;
    wTopMenu.selectMenuItem(menuItem);

    refreshSiteMenu(menuItem);
    westPanel.expand();
    GWTUtil.focus(wSiteMenu.getElement());

    QEntry entry = menuItem.getEntry();
    if (entry == null || entry.getLinks().size() == 0)
      return;
    QEntryLink link = (QEntryLink) entry.getLinks().get(0);
    RWindowCmpst window = this.getActiveWindow();
    if (window == null)
      window = this.addNewWindow();
    this.setActiveWindow(window);
    window.navigate(link.getUrl(), ModuleNavigator.VALUE_STYLE_SIMPLE);
  }

  /** 一个左边菜单被点击后的处理。 */
  public void clickSiteMenuItem(QMenuItem menuItem, boolean newWindow) throws ClientBizException {
    QEntry entry = menuItem.getEntry();
    if (entry == null || entry.getLinks().size() == 0)
      return;
    QEntryLink link = (QEntryLink) entry.getLinks().get(0);
    RWindowCmpst window = newWindow ? this.addNewWindow() : this.getActiveWindow();
    if (window == null)
      window = this.addNewWindow();
    this.setActiveWindow(window);
    window.navigate(link.getUrl(), ModuleNavigator.VALUE_STYLE_SIMPLE);
    
    if (!this.wSiteMenu.getMenu().hasChildren(menuItem))
      westPanel.collapse();
  }

  /** 在当前窗口中显示指定模块。 */
  public void showModule(String moduleURL) throws ClientBizException {
    RWindowCmpst win = this.getActiveWindow();
    if (win == null)
      win = this.addNewWindow();
    this.setActiveWindow(win);
    win.navigate(moduleURL);
  }

  /** 显示登录页面 */
  public void showEntry(String target) throws ClientBizException {
    this.moduleNavigator.navigate2(MODULEURL_ENTRY, target);
  }

  // --------------------------------------------------------------------------
  // 用户界面
  // --------------------------------------------------------------------------

  private static final int VALUE_PNLTOP_HEIGHT = 29;
  private static final String URL_DEFAULT_LOGO = "rumba/images/entry/rb_logo_covermain.jpg";

  /** 界面部件，位于最顶层。 */
  private Panel panel;
  /** 界面部件，位于{@link #panel}内。 */
  private Panel borderPanel;

  /** 界面部件，顶端区域，位于{@link #borderPanel}内。 */
  private Panel northPanel;
  /** 界面部件，位于屏幕顶部，位于{@link #northPanel}内。 */
  private HorizontalPanel pnlTop;
  /** LOGO图片 */
  private Image imgLogo;
  /** 顶级菜单 */
  private TopMenuCmpst wTopMenu = new TopMenuCmpst(this);
  /** 工具条 */
  private ToolbarCmpst wToolbar = new ToolbarCmpst(this);
  /** 登录信息 */
  private LogonInfoCmpst wLogonInfo = new LogonInfoCmpst(this);
  /** 时钟 */
  private ClockCmpst wClock = new ClockCmpst(this);

  /** 界面部件，左边区域，位于{@link #borderPanel}内。 */
  private Panel westPanel;
  /** 界面部件，对应{@link #westPanel}的Layout Data。 */
  private BorderLayoutData westData;
  /** 左边菜单 */
  private SiteMenuCmpst wSiteMenu = new SiteMenuCmpst(this);

  /** 界面部件，位于{@link #borderPanel}内，位于屏幕中间部分，用于摆放模块窗口。 */
  private TabPanel tabWindows;

  /** {@link #imgLogo}的时间侦听器 */
  private class Listener_imgLogo implements LoadListener {
    public void onError(Widget sender) {
      imgLogo.setUrl(GWTUtil.getStaticContentURL(URL_DEFAULT_LOGO));
    }

    public void onLoad(Widget sender) {
      // Do Nothing
    }
    
  }

  /** {@link #tabWindows}的事件侦听适配器。 */
  private ContainerListenerAdapter lstnTabWindows = new ContainerListenerAdapter() {
    public void onRemove(Container self, Component component) {
      if (getWindowCount() > 0)
        return;
      // 当关闭最后一个Window后，自动打开首页。
      try {
        showModule(MODULEURL_HOME);
      } catch (ClientBizException e) {
        MessageBox.alert(Window.getTitle(), "无法显示首页页面。\n" + e.getMessage());
      }
    }
  };

  private void drawSelf() {
    panel = new Panel();
    panel.setBorder(false);
    panel.setLayout(new FitLayout());

    borderPanel = new Panel();
    borderPanel.setLayout(new BorderLayout());

    draw_north();
    draw_west();
    draw_center();

    panel.add(borderPanel);
    new Viewport(panel);
  }

  private void draw_north() {
    northPanel = new Panel();
    northPanel.setHeight(VALUE_PNLTOP_HEIGHT);
    borderPanel.add(northPanel, new BorderLayoutData(RegionPosition.NORTH));

    pnlTop = new HorizontalPanel();
    pnlTop.setWidth("100%");
    pnlTop.setHeight("100%");
    pnlTop.setStyleName("rb-top-bg");

    imgLogo = new Image();
    imgLogo.setUrl(GWTUtil.getStaticContentURL(URL_DEFAULT_LOGO));
    imgLogo.addLoadListener(new Listener_imgLogo());
    imgLogo.setHeight("100%");
    pnlTop.add(imgLogo);
    pnlTop.add(wTopMenu);
    pnlTop.setCellWidth(wTopMenu, "100%");
    pnlTop.setCellVerticalAlignment(wTopMenu, HorizontalPanel.ALIGN_BOTTOM);
    pnlTop.add(wToolbar);
    pnlTop.setCellVerticalAlignment(wToolbar, HorizontalPanel.ALIGN_MIDDLE);
    Image img2 = new Image("images/top-seperator.jpg");
    pnlTop.add(img2);
    pnlTop.add(wLogonInfo);
    pnlTop.add(wClock);
    pnlTop.setCellHeight(wClock, "100%");

    northPanel.add(pnlTop);
  }

  private void draw_west() {
    westPanel = new Panel();
    westPanel.setTitle("菜单");
    westPanel.setCollapsible(true);
    westPanel.setWidth(140);

    westData = new BorderLayoutData(RegionPosition.WEST);
    westData.setSplit(true);
    westData.setMinSize(100);
    westData.setMaxSize(250);
    westData.setMargins(new Margins(0, 0, 0, 0));
    borderPanel.add(westPanel, westData);

    VerticalPanel vpnl = new VerticalPanel();
    vpnl.setWidth("100%");
    // TODO 画出菜单Toolbar。
    vpnl.add(wSiteMenu);
    westPanel.add(vpnl);
  }

  private void draw_center() {
    tabWindows = new TabPanel();
    tabWindows.addListener(lstnTabWindows);
    tabWindows.setDeferredRender(true);
    borderPanel.add(tabWindows, new BorderLayoutData(RegionPosition.CENTER));
    
  }
  
  private void loadCoverCartridge() {
    CartridgeService.Locator.getService().getCoverCartridge(new AsyncCallback() {

      public void onFailure(Throwable caught) {
        // Do Nothing
      }

      public void onSuccess(Object result) {
        QCartridge cart = (QCartridge) result;
        draw_coverCartridge(cart);
      }
      
    });
  }
  
  private void draw_coverCartridge(QCartridge cart) {
    String title = cart.getCaptionEN() + " - " + cart.getCaption();
    Window.setTitle(title);
    
    String logoUrl = (String) cart.getResources().get("logo_coverMain");
    if (logoUrl != null)
      imgLogo.setUrl(GWTUtil.getStaticContentURL(logoUrl));
  }

  // --------------------------------------------------------------------------
  // Module Navigator
  // --------------------------------------------------------------------------

  /** 首页url */
  public static final String MODULEURL_HOME = "welcome.Welcome/Welcome.html";
  /** 登录页面url */
  public static final String MODULEURL_ENTRY = "entry.Entry/Entry.html";
  /** 修改密码页面url */
  public static final String MODULEURL_CHANGEPWD = "bin/ViewApplication?start=changePwd";

  private ModuleNavigator moduleNavigator = new ModuleNavigator();

  /**
   * 取得所包含的模块导航器对象。
   * 
   * @return
   */
  ModuleNavigator getModuleNavigator() {
    return this.moduleNavigator;
  }

  // --------------------------------------------------------------------------
  // Windows
  // --------------------------------------------------------------------------

  /**
   * 取得当前窗口的数量。
   * 
   * @return
   */
  int getWindowCount() {
    return tabWindows.getItems().length;
  }

  /**
   * 取得指定的窗口。
   * 
   * @param index
   *          指定窗口的索引。
   * @return 返回取得窗口，若找不到将返回null。
   */
  RWindowCmpst getWindow(int index) {
    if (index < 0 || index >= this.getWindowCount())
      return null;
    return (RWindowCmpst) tabWindows.getItems()[index];
  }

  /**
   * 取得当前活动的窗口。
   * 
   * @return
   */
  RWindowCmpst getActiveWindow() {
    if (tabWindows.getItems().length == 0)
      return null;
    else
      return (RWindowCmpst) tabWindows.getActiveTab();
  }
  
  void setActiveWindow(RWindowCmpst window) {
    assert window != null;
    tabWindows.setActiveTab(window.getId());
  }

  /**
   * 创建并添加一个新的窗口。
   * 
   * @return 返回所创建的窗口。
   */
  RWindowCmpst addNewWindow() {
    RWindowCmpst window = new RWindowCmpst(this);
    tabWindows.add(window);
    return window;
  }

  // --------------------------------------------------------------------------
  // Misc
  // --------------------------------------------------------------------------

  private void refreshSiteMenu(QMenuItem topMenuItem) {
    wSiteMenu.clear();

    MainFrameService.Locator.getService().getSubMenu(topMenuItem.getId(), new AsyncCallback() {
      public void onFailure(Throwable t) {
        MessageBox.alert(Window.getTitle(), "从服务器取得主菜单信息时发生错误。\n" + t.getMessage());
      }

      public void onSuccess(Object result) {
        try {
          wSiteMenu.setMenu((QMenu) result);
          moduleNavigator.prepare();
        } catch (Exception e) {
          MessageBox.alert(Window.getTitle(), "显示主菜单时发生错误。\n" + e.getMessage());
        }
      }
    });
  }

  private void refreshLogInfo() {
    assert wLogonInfo != null;
    wLogonInfo.refresh();
  }

}
